package com.sne.monitor.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sne.common.constant.ScheduleConstants;
import com.sne.common.exception.CustomException;
import com.sne.common.util.ConvertUtils;
import com.sne.common.util.ScheduleUtil;
import com.sne.monitor.entity.MonitorTimeTask;
import com.sne.monitor.mapper.MonitorTimeTaskMapper;
import com.sne.monitor.service.IMonitorTimeTaskService;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.quartz.JobDataMap;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 定时任务服务实现类
 *
 * @author fanghh
 * @date 2020/12/7
 */
@Service
public class MonitorTimeTaskServiceImpl extends ServiceImpl<MonitorTimeTaskMapper, MonitorTimeTask> implements IMonitorTimeTaskService {


    @Autowired
    private Scheduler scheduler;

    @Override
    public Page findPage(Page page, MonitorTimeTask timeTask) {
        LambdaQueryWrapper<MonitorTimeTask> queryWrapper = Wrappers.<MonitorTimeTask>query().lambda();
        if (StringUtils.isNotBlank(timeTask.getTaskName())) {
            queryWrapper.like(MonitorTimeTask::getTaskName, timeTask.getTaskName());
        }
        if (timeTask.getState() != null) {
            queryWrapper.eq(MonitorTimeTask::getState, timeTask.getState());
        }
        if (StringUtils.isNotBlank(timeTask.getTaskGroup())) {
            queryWrapper.eq(MonitorTimeTask::getTaskGroup, timeTask.getTaskGroup());
        }
        queryWrapper.orderByDesc(MonitorTimeTask::getCreateTime);
        Page data = this.page(page, queryWrapper);
        return ConvertUtils.convert(data);
    }

    @SneakyThrows
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean saveTask(MonitorTimeTask timeTask) {
        this.save(timeTask);
        ScheduleUtil.createScheduleJob(scheduler, timeTask);
        return true;
    }

    @SneakyThrows
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean updateTask(MonitorTimeTask timeTask) {
        MonitorTimeTask task = this.getById(timeTask.getId());
        if(task == null){
            throw new CustomException("定时任务不存在");
        }
        this.updateById(timeTask);
        JobKey jobKey = ScheduleUtil.getJobKey(timeTask.getId(), timeTask.getTaskGroup());
        if (scheduler.checkExists(jobKey)) {
            scheduler.deleteJob(jobKey);
        }
        ScheduleUtil.createScheduleJob(scheduler, timeTask);
        return true;
    }

    @SneakyThrows
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean deleteById(Long id) {
        MonitorTimeTask task = getById(id);
        if(task == null){
            throw new CustomException("定时任务不存在");
        }
        this.deleteById(id);
        scheduler.deleteJob(ScheduleUtil.getJobKey(task.getId(), task.getTaskGroup()));
        return true;
    }

    @SneakyThrows
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean deleteByIds(List<Long> ids) {
        List<MonitorTimeTask> tasks = this.list(Wrappers.<MonitorTimeTask>query()
                .lambda().in(MonitorTimeTask::getId, ids));
        if(CollectionUtils.isEmpty(tasks)){
            throw new CustomException("定时任务不存在");
        }
        this.removeByIds(ids);
        List<JobKey> jobKeyList = tasks.stream().map(task -> ScheduleUtil.getJobKey(task.getId(), task.getTaskGroup())).collect(Collectors.toList());
        scheduler.deleteJobs(jobKeyList);
        return true;
    }

    @SneakyThrows
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean changeState(MonitorTimeTask task) {
        MonitorTimeTask timeTask = getById(task.getId());
        if(timeTask == null){
            throw new CustomException("定时任务不存在");
        }
        JobKey jobKey = ScheduleUtil.getJobKey(timeTask.getId(), timeTask.getTaskGroup());
        if(task.getState()){
            scheduler.resumeJob(jobKey);
        }else {
            scheduler.pauseJob(jobKey);
        }
        return true;
    }

    @SneakyThrows
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean run(Long id) {
        MonitorTimeTask task = getById(id);
        if(task == null){
            throw new CustomException("定时任务不存在");
        }
        JobDataMap dataMap = new JobDataMap();
        dataMap.put(ScheduleConstants.TASK_PROPERTIES,task);
        scheduler.triggerJob(ScheduleUtil.getJobKey(task.getId(),task.getTaskGroup()),dataMap);
        return true;
    }

}
